#! /usr/bin/env python
# coding:utf-8


from pyecharts import options as opts
from pyecharts.charts import *
from pyecharts.globals import ThemeType
from pyecharts.components import Table
from pyecharts.faker import Faker

from random import randint

import sqlite3
import datetime
import pandas as pd

class Gen_Charts():

    def __init__(self):
        self.con = sqlite3.connect('local.db')
        self.cur = self.con.cursor()
        self.cur.execute('select max(date),min(date) from disease')
        date_rslt = self.cur.fetchone()

        today = datetime.datetime.today()
        if not date_rslt[0]:
            max_date = datetime.datetime(today.year,today.month,today.day,12,0,0).timestamp()
        else:
            max_date =date_rslt[0] + 1
        if not date_rslt[1]:
            min_date = (datetime.datetime(today.year,today.month,today.day,12,0,0) - datetime.timedelta(30)).timestamp()
        else:
            min_date = date_rslt[1]

        self.date_list = []
        for i in range(min_date,max_date,86400):
            self.date_list.append(i)

        self.day = datetime.datetime.strftime(datetime.datetime.fromtimestamp(max_date),'%Y-%m-%d')

    def gen_line(self,data_dic,title_dic):
            xaxis = data_dic['xaxis']
            yaxis = data_dic['yaxis']
            len_xaxis = len(xaxis)
            yaxis2 = [None]*7
            for i in range(7,len_xaxis):
                tmp = int(sum(yaxis[i-7:i])/7)
                yaxis2.append(tmp)
            line = (Line(init_opts = opts.InitOpts(theme=ThemeType.MACARONS, chart_id = title_dic['chart_id']))
                    .add_xaxis(xaxis)
                    .add_yaxis("报告数",yaxis,is_smooth = True, is_symbol_show = False,
                               markpoint_opts = opts.MarkPointOpts(
                                data = [
                                        opts.MarkPointItem(type_ = 'max', name= '最大值'),
                                        opts.MarkPointItem(type_ = 'min', name= '最小值'),
                                    ]
                               ),
                               # markline_opts = opts.MarkLineOpts(
                                # data = [opts.MarkLineItem(type_='average',name='平均值')]
                               # )
                               )
                    # .set_series_opts(
                    #                 itemstyle_opts = {"normal":{'color':"#ff0000"}}
                    #         )
                    .add_yaxis('7d移动平均',yaxis2,is_smooth = True, is_symbol_show = False,
                             )
                    .set_global_opts(title_opts = opts.TitleOpts(title=title_dic['title'],pos_left='5%'),
                                    axispointer_opts = opts.AxisPointerOpts(
                                        is_show = True, link =[{'xAxisIndex':'all'}]
                                    ),
                                    tooltip_opts = opts.TooltipOpts(trigger = 'axix'),
                                    datazoom_opts = [
                                        opts.DataZoomOpts(
                                            is_show = True,
                                            is_realtime = True,
                                            range_start = 0,
                                            range_end = 100
                                        )
                                    ],
                                    )
                    )
            return line

    def gen_bar(self,data_dic,title_dic):

        bar = (Bar(init_opts=opts.InitOpts(theme=ThemeType.MACARONS, chart_id=title_dic['chart_id']))
                .add_xaxis(data_dic['stack_x_axis'])
                .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
                .set_global_opts(title_opts=opts.TitleOpts(title=title_dic['title'],pos_left='5%'),
                        datazoom_opts = [
                            opts.DataZoomOpts(
                                is_show = True,
                                is_realtime = True,
                                range_start = 0,
                                range_end = 100
                            )
                        ])
            )
        for k,v in data_dic['stack_y_axises'].items():
            bar.add_yaxis(k,v,stack='stack1').set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        return bar

    def gen_pie(self,data_dic,title_dic):
        x_data = data_dic['xaxis']
        y_data = data_dic['yaxis']
        data_pair = [list(z) for z in zip(x_data,y_data)]

        pie = (Pie(init_opts=opts.InitOpts(theme=ThemeType.MACARONS, chart_id=title_dic['chart_id']))
                .add(
                "",
                data_pair,
                rose乙类pe="radius",
                radius="55%",
                center=["50%", "50%"],
                )
                    .set_global_opts(title_opts=opts.TitleOpts(
                    title=title_dic['title'],
                    pos_left="center",
                    pos_top="25",
                ),
                    legend_opts=opts.LegendOpts(is_show=False),
                )
            )
        return pie


    def gen_map(self,data,title_dic):
        tl = (Timeline(init_opts=opts.InitOpts(theme=ThemeType.MACARONS,chart_id = title_dic['chart_id']))
            .add_schema(is_auto_play = True,play_interval=1000,symbol_size=1))
        date_list = data['date_list']
        city_list = data['city_list']
        len_ = len(date_list)
        for i in range(len_):
            c = (
                Map(init_opts=opts.InitOpts(theme=ThemeType.MACARONS))
                .add("", city_list[i], "安徽")
                .set_global_opts(
                    title_opts=opts.TitleOpts(title=title_dic['title'],pos_left='center'),
                    visualmap_opts=opts.VisualMapOpts(
                        min_ = 0,
                        max_ = 100,
                        split_number= 10,
                        # range_color = []
                        pos_left = '5%',
                        pos_bottom = '5%'
                    )
                ))
            tl.add(c,'{}'.format(date_list[i]))

        return tl

    def gen_geo(self,data):
        tl = Timeline(init_opts=opts.InitOpts(chart_id = 2))
        for i in range(10):
            geo = (
                Geo()
                .add_schema(maptype='安徽')
                .add("", [list(z) for z in zip(['合肥市','芜湖市','黄山市'],[randint(1,300) for i in range(3)])], "安徽")
                .set_series_opts(label_opts=opts.LabelOpts(is_show_False))
                .set_global_opts(visualmap_opts=opts.VisualMapOpts(),
                    title_opts=opts.TitleOpts(title="abc"))
            )
            tl.add(geo,'{}'.format(i))
        return tl

    def gen_themeriver(self,data_dic,title_dic):
        x_data = data_dic['x_data']
        y_data = data_dic['y_data']
        title = title_dic['title']
        chart_id = title_dic['chart_id']

        c = (
            ThemeRiver(init_opts=opts.InitOpts(theme=ThemeType.MACARONS,chart_id=chart_id))
            .add(
                series_name=x_data,
                data=y_data,
                singleaxis_opts=opts.SingleAxisOpts(
                    pos_top="50", pos_bottom="50", type_="time"
                ),
                )
            .set_global_opts(title_opts = opts.TitleOpts(title=title,subtitle='截止到{}'.format(self.day),pos_left='5%'),
                            axispointer_opts = opts.AxisPointerOpts(
                                        is_show = True, link =[{'xAxisIndex':'all'}]
                                    ),
                            tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="line"),
                            datazoom_opts = [
                                        opts.DataZoomOpts(
                                            is_show = True,
                                            is_realtime = True,
                                            range_start = 0,
                                            range_end = 100
                                                )
                                        ]
                                    )
            )
        return c

    def gen_table(self,data_dic,title_dic):
        head = data_dic['head']
        rows = data_dic['rows']
        c = Table()
        c.chart_id = title_dic['chart_id']
        c.add(head,rows).set_global_opts(
                {'title':title_dic['title'],
                'title_style':'style="color:red"'}
            )

        return c

    def gen_hetmap(self,data_dic,title_dic):
        value = data_dic['heat_value']
        c = (
            HeatMap(init_opts=opts.InitOpts(theme=ThemeType.MACARONS,chart_id=title_dic['chart_id']))
            .add_xaxis(data_dic['heat_xaixs'])
            .add_yaxis(
                "",
                data_dic['heat_yaxis'],
                value,
                label_opts=opts.LabelOpts(is_show=True, position="inside"),
            )
            .set_global_opts(
                title_opts=opts.TitleOpts(title=title_dic['title'],pos_left='5%'),
                visualmap_opts=opts.VisualMapOpts(
                            min_=data_dic['heat_min'],
                            max_=data_dic['heat_max'],
                            pos_left = '1%',
                            pos_bottom = '10%'
                            ),
            datazoom_opts = [
                    opts.DataZoomOpts(
                        is_show = True,
                        is_realtime = True,
                        range_start = 0,
                        range_end = 100
                    )
                ],
            )
        )
        return c

    def gen_scatter_single(self):
        pass


    def dashboard(self,data_dic):

        page = (
            Page(layout = Page.DraggablePageLayout)
            .add(
                self.gen_themeriver(data_dic,{'title':'传染病分类统计图','chart_id':1}),
                self.gen_map(data_dic,{'title':'报告传染病地图','chart_id':2}),
                self.gen_line(data_dic,{'title':'曲线图','chart_id':3}),
                self.gen_bar(data_dic,{"title":'性传播疾病','chart_id':4}),
                self.gen_hetmap(data_dic,{'title':'传染病分类统计图','chart_id':5}),
                self.gen_table(data_dic,{"title":'一览表','chart_id':6}),
                )
            )

        page.render('page.html')
        Page.save_resize_html('page.html',
                              cfg_file = 'chart_config.json',
                              dest = 'dashboard.html')

    def gen_data(self):

        rslt = pd.read_sql('select a.*,b.lei,b.type from disease as a,lei as b where a.disease = b.disease',self.con)
        # min_date = rslt['date'].min()
        # max_date = rslt['date'].max()
        # today = datetime.datetime.today()
        # if not max_date:
        #     max_date = datetime.datetime(today.year,today.month,today.day,12,0,0)
        # if not min_date:
        #     min_date = datetime.datetime(today.year,today.month,today.day,12,0,0) - datetime.timedelta(30)
        # gap = int((max_date - min_date)/86400) + 1
        # date = []
        # for i in range(gap):
        #     date.append(min_date+86400*i)
        date = self.date_list

        rslt2 = rslt.groupby(['date']).sum().reset_index()

        xaxis = []
        yaxis = []
        x_data = ["甲类", "乙类", "丙类", "其他"]
        y_data = []
        for i in date:
            date2 = datetime.datetime.strftime(datetime.datetime.fromtimestamp(i),'%Y/%m/%d')
            xaxis.append(date2)
            # if i in list(rslt2['date']):
            yaxis.append(int(rslt2[rslt2['date']==i]['count'].sum()))
            # else:
                # yaxis.append(0)
        for j in x_data:
            for i in date:
                date3 = datetime.datetime.strftime(datetime.datetime.fromtimestamp(i),'%Y/%m/%d')
                tmp = rslt[(rslt['date'] == i) & (rslt['lei'] == j)]['count'].sum()
                y_data.append([date3,int(tmp),j])


        # city_rslt =  rslt.groupby(['date','city'])['count'].sum().reset_index()
        # date_list = []
        # city_list = []
        # for i in date:
        #     date_tmp = datetime.datetime.strftime(datetime.datetime.fromtimestamp(i),'%m/%d')
        #     date_list.append(date_tmp)
        #     tmp_rslt = rslt[rslt['date']==i]
        #     if not tmp_rslt.empty:
        #         city_list.append([list(z) for z in zip(list(tmp_rslt['city']),list(tmp_rslt['count']))])
        #     else:
        #         city_list.append([['合肥市',0]])
        city_list = self.gen_cum_sum(rslt)


        rslt3 = rslt.groupby(['date','city']).sum().reset_index()
        heat_map_data = self.gen_hetmap_data(rslt3)

        rslt4= rslt[rslt['type'].str.contains('性传播疾病')].groupby(['date','disease']).sum().reset_index()
        stack_data_dic = self.gen_stack_data(rslt4)

        table_dic = self.gen_table_data(rslt3)

        data_dic = {'xaxis':xaxis,'yaxis':yaxis,'x_data':x_data,'y_data':y_data,
                    'date_list':city_list[0],'city_list':city_list[1],
                    }
        data_dic.update(heat_map_data)
        data_dic.update(table_dic)
        data_dic.update(stack_data_dic)

        return data_dic


    def gen_stack_data(self,df):
        if not df.empty:
            max_date  = df['date'].max() + 86401
            min_date =  df['date'].min()
            dates = []
            disease = list(set(list(df['disease'])))
            counts = {}
            for i in disease:
                tmp_count = []
                for j in range(min_date,max_date,86400):
                    tmp = df[(df['date']==j)&(df['disease'] == i)]
                    if tmp.empty:
                        tmp_count.append(0)
                    else:
                       tmp_count.append(int(tmp['count']))
                counts[i] = tmp_count

            for i in range(min_date,max_date,86400):
                date2 = datetime.datetime.strftime(datetime.datetime.fromtimestamp(i),'%m/%d')
                dates.append(date2)
        dic = {'stack_x_axis':dates,'stack_y_axises':counts}
        return dic


    def gen_cum_sum(self,df,cum_mark=1):

        date = self.date_list
        city_rslt =  df.groupby(['date','city'])['count'].sum().reset_index()
        date_list = []
        city_list = []
        city_dic = {}
        for i in date:
            date_tmp = datetime.datetime.strftime(datetime.datetime.fromtimestamp(i),'%m/%d')
            date_list.append(date_tmp)
            tmp_rslt = df[df['date']==i]
            if not tmp_rslt.empty:
                city_tmp = list(tmp_rslt['city'])
                count_tmp = list(tmp_rslt['count'])
                len_tmp = len(city_tmp)
                for i in range(len_tmp):
                    if city_tmp[i] in city_dic.keys() and cum_mark:
                        city_dic[city_tmp[i]] += count_tmp[i]
                    else:
                        city_dic[city_tmp[i]] = count_tmp[i]
                zip_tmp = [[k,int(v)] for k,v in city_dic.items()]
                city_list.append(zip_tmp)
            else:
                city_list.append([['合肥市',0]])

        return date_list,city_list

    def gen_hetmap_data(self,df):

        date_list  = self.date_list
        date_list2 = []
        for i in date_list:
            date2 = datetime.datetime.strftime(datetime.datetime.fromtimestamp(i),'%Y/%m/%d')
            date_list2.append(date2)
        city_rslt =  df.groupby(['date','city'])['count'].sum().reset_index()
        city_list  = list(set(list(city_rslt['city'])))
        city_dic = []
        len_city_list = len(city_list)
        len_date_list = len(date_list)
        for i in range(len_city_list):
            for j in range(len_date_list):
                tmp = city_rslt[(city_rslt['date']==date_list[j])&(city_rslt['city']==city_list[i])]['count'].sum()
                if tmp:
                    city_dic.append([j,i,int(tmp)])
                else:
                    city_dic.append([j,i,0])
        heat_max = int(df['count'].max())
        heat_min_tmp = int(df['count'].min())
        if heat_min_tmp > 0:
            heat_min = 0
        else:
            heat_min = heat_min_tmp

        heat_dic = {
            'heat_max':heat_max,
            'heat_min':heat_min,
            'heat_xaixs':date_list2,
            'heat_yaxis':city_list,
            'heat_value':city_dic
        }
        return heat_dic

    def gen_table_data(self,df):
        if not df.empty:
            heads_tmp = list(set(list(df['city'])))
            max_date  = df['date'].max() + 86401
            min_date =  df['date'].min()
            rows = []
            for i in range(min_date,max_date,86400):
                date2 = datetime.datetime.strftime(datetime.datetime.fromtimestamp(i),'%Y/%m/%d')
                city_count = [df[df['date']==i]['count'].sum(),]
                for j in heads_tmp:
                    tmp = df[(df['date']==i)&(df['city'] == j)]
                    if tmp.empty:
                        city_count.append('-')
                    else:
                        city_count.append(tmp['count'].sum())
                rows.append([date2]+city_count)
            heads = ['日期','合计'] + heads_tmp
        dic = {'head':heads,'rows':rows}
        return dic



if __name__ == "__main__":
    tmp = Gen_Charts()
    data = tmp.gen_data()
    tmp.dashboard(data)
